package com.cyw.common.utils;

import com.cyw.common.exceptions.ParamCheckException;
import org.hibernate.validator.HibernateValidator;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.groups.Default;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.cyw.common.utils.BaseUtils.*;


public class CheckUtils {
    private static final Validator validator;

    static {
        validator = Validation.byProvider(HibernateValidator.class)
                .configure()
                .buildValidatorFactory()
                .getValidator();
    }

    public static Validator getValidator() {
        return validator;
    }

    public static void isTrue(boolean expression, String str) {
        if (!expression) {
            throw new ParamCheckException(str);
        }
    }

    public static void checkId(Serializable o) {
        if (o == null) {
            throw new ParamCheckException("id不能为空");
        }
    }

    public static void moreThanZeroThr(Integer b, String str) {
        if (b <= 0) {
            throw new ParamCheckException(str + "应大于0");
        }
    }

    public static void moreThanZeroThr(Long b, String str) {
        if (b <= 0L) {
            throw new ParamCheckException(str + "应大于0");
        }
    }

    public static void moreThanZeroThr(BigDecimal b, String str) {
        if (BigDecimal.ZERO.compareTo(b) > 0) {
            throw new ParamCheckException(str + "应大于0");
        }
    }

    public static void moreThanOneThr(BigDecimal b, String str) {
        if (b.compareTo(BigDecimal.ONE) > 0) {
            throw new ParamCheckException(str + "应小于1");
        }
    }

    public static void checkNull(Object o, String entityName) {
        if (o == null) {
            throw new ParamCheckException(entityName + "不能为空");
        }
    }

    public static void checkEmpty(String o, String entityName) {
        if (isEmpty(o)) {
            throw new ParamCheckException(entityName + "不能为空");
        }
    }

    public static void checkEmpty(Iterable<?> c, String entityName) {
        if (BaseUtils.isEmpty(c)) {
            throw new ParamCheckException(entityName + "不能为空");
        }
    }

    public static void checkEmpty(Object[] arr, String entityName) {
        if (arr == null || arr.length == 0) {
            throw new ParamCheckException(entityName + "不能为空");
        }
    }

    public static void checkEmpty(Map<?, ?> map, String entityName) {
        if (isNull(map) || map.isEmpty()) {
            throw new ParamCheckException(entityName + "不能为空");
        }
    }

    public static void check(Object obj, String entityName) {
        check(obj, entityName, Default.class);
    }

    public static void check(Object obj, String entityName, Class<? extends Default>... groups) {
        checkNull(obj, entityName);
        checkValidationGroup(groups);

        String errMsg = getErrMsg(obj, groups);

        if (isNotEmpty(errMsg)) {
            throw new ParamCheckException(errMsg);
        }
    }

    public static void check(Collection<?> c, String entityName) {
        check(c, entityName, Default.class);
    }

    public static void check(Collection<?> c, String entityName, Class<? extends Default>... groups) {
        checkEmpty(c, entityName);
        checkValidationGroup(groups);

        StringBuffer errMsg = new StringBuffer("");
        for (Object o : c) {
            errMsg.append(getErrMsg(o, groups));
        }

        if (isNotEmpty(errMsg)) {
            throw new ParamCheckException(errMsg.toString());
        }
    }

    private static String getErrMsg(Object obj) {
        return getErrMsg(obj, Default.class);
    }

    private static String getErrMsg(Object obj, Class<? extends Default>... groups) {
        checkValidationGroup(groups);
        Set<ConstraintViolation<Object>> validate = validator.validate(obj, groups);

        return validate.stream()
                .map(ConstraintViolation::getMessage)
                .filter(BaseUtils::isNoneEmpty)
                .collect(Collectors.joining(";"));
    }

    private static void checkValidationGroup(Class<? extends Default>[] groups) {
        isEmptyThr(groups, "校验groups 不能为空");
    }
}
